/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package daos;

import businessObjects.Pais;
import daos.exceptions.IllegalOrphanException;
import daos.exceptions.NonexistentEntityException;
import daos.exceptions.PreexistingEntityException;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import businessObjects.Cliente;
import java.util.ArrayList;
import java.util.Collection;
import businessObjects.Formulario;

/**
 *
 * @author williamprado
 */
public class PaisDAO {

    public PaisDAO() {
        //emf = Persistence.createEntityManagerFactory("Adz-ejbPU");
    }
    //private EntityManagerFactory emf = null;

    /*public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }*/

    /*public void create(Pais pais) throws PreexistingEntityException, Exception {
        if (pais.getClienteCollection() == null) {
            pais.setClienteCollection(new ArrayList<Cliente>());
        }
        if (pais.getFormularioCollection() == null) {
            pais.setFormularioCollection(new ArrayList<Formulario>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Collection<Cliente> attachedClienteCollection = new ArrayList<Cliente>();
            for (Cliente clienteCollectionClienteToAttach : pais.getClienteCollection()) {
                clienteCollectionClienteToAttach = em.getReference(clienteCollectionClienteToAttach.getClass(), clienteCollectionClienteToAttach.getLogin());
                attachedClienteCollection.add(clienteCollectionClienteToAttach);
            }
            pais.setClienteCollection(attachedClienteCollection);
            Collection<Formulario> attachedFormularioCollection = new ArrayList<Formulario>();
            for (Formulario formularioCollectionFormularioToAttach : pais.getFormularioCollection()) {
                formularioCollectionFormularioToAttach = em.getReference(formularioCollectionFormularioToAttach.getClass(), formularioCollectionFormularioToAttach.getIdFormulario());
                attachedFormularioCollection.add(formularioCollectionFormularioToAttach);
            }
            pais.setFormularioCollection(attachedFormularioCollection);
            em.persist(pais);
            for (Cliente clienteCollectionCliente : pais.getClienteCollection()) {
                Pais oldPaisOfClienteCollectionCliente = clienteCollectionCliente.getPais();
                clienteCollectionCliente.setPais(pais);
                clienteCollectionCliente = em.merge(clienteCollectionCliente);
                if (oldPaisOfClienteCollectionCliente != null) {
                    oldPaisOfClienteCollectionCliente.getClienteCollection().remove(clienteCollectionCliente);
                    oldPaisOfClienteCollectionCliente = em.merge(oldPaisOfClienteCollectionCliente);
                }
            }
            for (Formulario formularioCollectionFormulario : pais.getFormularioCollection()) {
                Pais oldPaisOfFormularioCollectionFormulario = formularioCollectionFormulario.getPais();
                formularioCollectionFormulario.setPais(pais);
                formularioCollectionFormulario = em.merge(formularioCollectionFormulario);
                if (oldPaisOfFormularioCollectionFormulario != null) {
                    oldPaisOfFormularioCollectionFormulario.getFormularioCollection().remove(formularioCollectionFormulario);
                    oldPaisOfFormularioCollectionFormulario = em.merge(oldPaisOfFormularioCollectionFormulario);
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            if (findPais(pais.getCcode()) != null) {
                throw new PreexistingEntityException("Pais " + pais + " already exists.", ex);
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }*/

    public void create(Pais pais, EntityManager em) throws PreexistingEntityException, Exception {
        if (pais.getClienteCollection() == null) {
            pais.setClienteCollection(new ArrayList<Cliente>());
        }
        if (pais.getFormularioCollection() == null) {
            pais.setFormularioCollection(new ArrayList<Formulario>());
        }
        //EntityManager em = null;
        try {
            //em = getEntityManager();
            //em.getTransaction().begin();
            Collection<Cliente> attachedClienteCollection = new ArrayList<Cliente>();
            for (Cliente clienteCollectionClienteToAttach : pais.getClienteCollection()) {
                clienteCollectionClienteToAttach = em.getReference(clienteCollectionClienteToAttach.getClass(), clienteCollectionClienteToAttach.getLogin());
                attachedClienteCollection.add(clienteCollectionClienteToAttach);
            }
            pais.setClienteCollection(attachedClienteCollection);
            Collection<Formulario> attachedFormularioCollection = new ArrayList<Formulario>();
            for (Formulario formularioCollectionFormularioToAttach : pais.getFormularioCollection()) {
                formularioCollectionFormularioToAttach = em.getReference(formularioCollectionFormularioToAttach.getClass(), formularioCollectionFormularioToAttach.getIdFormulario());
                attachedFormularioCollection.add(formularioCollectionFormularioToAttach);
            }
            pais.setFormularioCollection(attachedFormularioCollection);
            em.persist(pais);
            for (Cliente clienteCollectionCliente : pais.getClienteCollection()) {
                Pais oldPaisOfClienteCollectionCliente = clienteCollectionCliente.getPais();
                clienteCollectionCliente.setPais(pais);
                clienteCollectionCliente = em.merge(clienteCollectionCliente);
                if (oldPaisOfClienteCollectionCliente != null) {
                    oldPaisOfClienteCollectionCliente.getClienteCollection().remove(clienteCollectionCliente);
                    oldPaisOfClienteCollectionCliente = em.merge(oldPaisOfClienteCollectionCliente);
                }
            }
            for (Formulario formularioCollectionFormulario : pais.getFormularioCollection()) {
                Pais oldPaisOfFormularioCollectionFormulario = formularioCollectionFormulario.getPais();
                formularioCollectionFormulario.setPais(pais);
                formularioCollectionFormulario = em.merge(formularioCollectionFormulario);
                if (oldPaisOfFormularioCollectionFormulario != null) {
                    oldPaisOfFormularioCollectionFormulario.getFormularioCollection().remove(formularioCollectionFormulario);
                    oldPaisOfFormularioCollectionFormulario = em.merge(oldPaisOfFormularioCollectionFormulario);
                }
            }
            //em.getTransaction().commit();
        } catch (Exception ex) {
            if (findPais(pais.getCcode(), em) != null) {
                throw new PreexistingEntityException("Pais " + pais + " already exists.", ex);
            }
            throw ex;
        }
    }

    /*public void edit(Pais pais) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Pais persistentPais = em.find(Pais.class, pais.getCcode());
            Collection<Cliente> clienteCollectionOld = persistentPais.getClienteCollection();
            Collection<Cliente> clienteCollectionNew = pais.getClienteCollection();
            Collection<Formulario> formularioCollectionOld = persistentPais.getFormularioCollection();
            Collection<Formulario> formularioCollectionNew = pais.getFormularioCollection();
            List<String> illegalOrphanMessages = null;
            for (Cliente clienteCollectionOldCliente : clienteCollectionOld) {
                if (!clienteCollectionNew.contains(clienteCollectionOldCliente)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Cliente " + clienteCollectionOldCliente + " since its pais field is not nullable.");
                }
            }
            for (Formulario formularioCollectionOldFormulario : formularioCollectionOld) {
                if (!formularioCollectionNew.contains(formularioCollectionOldFormulario)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Formulario " + formularioCollectionOldFormulario + " since its pais field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Collection<Cliente> attachedClienteCollectionNew = new ArrayList<Cliente>();
            for (Cliente clienteCollectionNewClienteToAttach : clienteCollectionNew) {
                clienteCollectionNewClienteToAttach = em.getReference(clienteCollectionNewClienteToAttach.getClass(), clienteCollectionNewClienteToAttach.getLogin());
                attachedClienteCollectionNew.add(clienteCollectionNewClienteToAttach);
            }
            clienteCollectionNew = attachedClienteCollectionNew;
            pais.setClienteCollection(clienteCollectionNew);
            Collection<Formulario> attachedFormularioCollectionNew = new ArrayList<Formulario>();
            for (Formulario formularioCollectionNewFormularioToAttach : formularioCollectionNew) {
                formularioCollectionNewFormularioToAttach = em.getReference(formularioCollectionNewFormularioToAttach.getClass(), formularioCollectionNewFormularioToAttach.getIdFormulario());
                attachedFormularioCollectionNew.add(formularioCollectionNewFormularioToAttach);
            }
            formularioCollectionNew = attachedFormularioCollectionNew;
            pais.setFormularioCollection(formularioCollectionNew);
            pais = em.merge(pais);
            for (Cliente clienteCollectionNewCliente : clienteCollectionNew) {
                if (!clienteCollectionOld.contains(clienteCollectionNewCliente)) {
                    Pais oldPaisOfClienteCollectionNewCliente = clienteCollectionNewCliente.getPais();
                    clienteCollectionNewCliente.setPais(pais);
                    clienteCollectionNewCliente = em.merge(clienteCollectionNewCliente);
                    if (oldPaisOfClienteCollectionNewCliente != null && !oldPaisOfClienteCollectionNewCliente.equals(pais)) {
                        oldPaisOfClienteCollectionNewCliente.getClienteCollection().remove(clienteCollectionNewCliente);
                        oldPaisOfClienteCollectionNewCliente = em.merge(oldPaisOfClienteCollectionNewCliente);
                    }
                }
            }
            for (Formulario formularioCollectionNewFormulario : formularioCollectionNew) {
                if (!formularioCollectionOld.contains(formularioCollectionNewFormulario)) {
                    Pais oldPaisOfFormularioCollectionNewFormulario = formularioCollectionNewFormulario.getPais();
                    formularioCollectionNewFormulario.setPais(pais);
                    formularioCollectionNewFormulario = em.merge(formularioCollectionNewFormulario);
                    if (oldPaisOfFormularioCollectionNewFormulario != null && !oldPaisOfFormularioCollectionNewFormulario.equals(pais)) {
                        oldPaisOfFormularioCollectionNewFormulario.getFormularioCollection().remove(formularioCollectionNewFormulario);
                        oldPaisOfFormularioCollectionNewFormulario = em.merge(oldPaisOfFormularioCollectionNewFormulario);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                String id = pais.getCcode();
                if (findPais(id) == null) {
                    throw new NonexistentEntityException("The pais with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }*/

    public void edit(Pais pais, EntityManager em) throws IllegalOrphanException, NonexistentEntityException, Exception {
        //EntityManager em = null;
        try {
            //em = getEntityManager();
            //em.getTransaction().begin();
            Pais persistentPais = em.find(Pais.class, pais.getCcode());
            Collection<Cliente> clienteCollectionOld = persistentPais.getClienteCollection();
            Collection<Cliente> clienteCollectionNew = pais.getClienteCollection();
            Collection<Formulario> formularioCollectionOld = persistentPais.getFormularioCollection();
            Collection<Formulario> formularioCollectionNew = pais.getFormularioCollection();
            List<String> illegalOrphanMessages = null;
            for (Cliente clienteCollectionOldCliente : clienteCollectionOld) {
                if (!clienteCollectionNew.contains(clienteCollectionOldCliente)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Cliente " + clienteCollectionOldCliente + " since its pais field is not nullable.");
                }
            }
            for (Formulario formularioCollectionOldFormulario : formularioCollectionOld) {
                if (!formularioCollectionNew.contains(formularioCollectionOldFormulario)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Formulario " + formularioCollectionOldFormulario + " since its pais field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Collection<Cliente> attachedClienteCollectionNew = new ArrayList<Cliente>();
            for (Cliente clienteCollectionNewClienteToAttach : clienteCollectionNew) {
                clienteCollectionNewClienteToAttach = em.getReference(clienteCollectionNewClienteToAttach.getClass(), clienteCollectionNewClienteToAttach.getLogin());
                attachedClienteCollectionNew.add(clienteCollectionNewClienteToAttach);
            }
            clienteCollectionNew = attachedClienteCollectionNew;
            pais.setClienteCollection(clienteCollectionNew);
            Collection<Formulario> attachedFormularioCollectionNew = new ArrayList<Formulario>();
            for (Formulario formularioCollectionNewFormularioToAttach : formularioCollectionNew) {
                formularioCollectionNewFormularioToAttach = em.getReference(formularioCollectionNewFormularioToAttach.getClass(), formularioCollectionNewFormularioToAttach.getIdFormulario());
                attachedFormularioCollectionNew.add(formularioCollectionNewFormularioToAttach);
            }
            formularioCollectionNew = attachedFormularioCollectionNew;
            pais.setFormularioCollection(formularioCollectionNew);
            pais = em.merge(pais);
            for (Cliente clienteCollectionNewCliente : clienteCollectionNew) {
                if (!clienteCollectionOld.contains(clienteCollectionNewCliente)) {
                    Pais oldPaisOfClienteCollectionNewCliente = clienteCollectionNewCliente.getPais();
                    clienteCollectionNewCliente.setPais(pais);
                    clienteCollectionNewCliente = em.merge(clienteCollectionNewCliente);
                    if (oldPaisOfClienteCollectionNewCliente != null && !oldPaisOfClienteCollectionNewCliente.equals(pais)) {
                        oldPaisOfClienteCollectionNewCliente.getClienteCollection().remove(clienteCollectionNewCliente);
                        oldPaisOfClienteCollectionNewCliente = em.merge(oldPaisOfClienteCollectionNewCliente);
                    }
                }
            }
            for (Formulario formularioCollectionNewFormulario : formularioCollectionNew) {
                if (!formularioCollectionOld.contains(formularioCollectionNewFormulario)) {
                    Pais oldPaisOfFormularioCollectionNewFormulario = formularioCollectionNewFormulario.getPais();
                    formularioCollectionNewFormulario.setPais(pais);
                    formularioCollectionNewFormulario = em.merge(formularioCollectionNewFormulario);
                    if (oldPaisOfFormularioCollectionNewFormulario != null && !oldPaisOfFormularioCollectionNewFormulario.equals(pais)) {
                        oldPaisOfFormularioCollectionNewFormulario.getFormularioCollection().remove(formularioCollectionNewFormulario);
                        oldPaisOfFormularioCollectionNewFormulario = em.merge(oldPaisOfFormularioCollectionNewFormulario);
                    }
                }
            }
            //em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                String id = pais.getCcode();
                if (findPais(id, em) == null) {
                    throw new NonexistentEntityException("The pais with id " + id + " no longer exists.");
                }
            }
            throw ex;
        }
    }

    /*public void destroy(String id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Pais pais;
            try {
                pais = em.getReference(Pais.class, id);
                pais.getCcode();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The pais with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Collection<Cliente> clienteCollectionOrphanCheck = pais.getClienteCollection();
            for (Cliente clienteCollectionOrphanCheckCliente : clienteCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Pais (" + pais + ") cannot be destroyed since the Cliente " + clienteCollectionOrphanCheckCliente + " in its clienteCollection field has a non-nullable pais field.");
            }
            Collection<Formulario> formularioCollectionOrphanCheck = pais.getFormularioCollection();
            for (Formulario formularioCollectionOrphanCheckFormulario : formularioCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Pais (" + pais + ") cannot be destroyed since the Formulario " + formularioCollectionOrphanCheckFormulario + " in its formularioCollection field has a non-nullable pais field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            em.remove(pais);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }*/

    public void destroy(String id, EntityManager em) throws IllegalOrphanException, NonexistentEntityException, Exception {
        //EntityManager em = null;
        try {
            //em = getEntityManager();
            //em.getTransaction().begin();
            Pais pais;
            try {
                pais = em.getReference(Pais.class, id);
                pais.getCcode();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The pais with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            Collection<Cliente> clienteCollectionOrphanCheck = pais.getClienteCollection();
            for (Cliente clienteCollectionOrphanCheckCliente : clienteCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Pais (" + pais + ") cannot be destroyed since the Cliente " + clienteCollectionOrphanCheckCliente + " in its clienteCollection field has a non-nullable pais field.");
            }
            Collection<Formulario> formularioCollectionOrphanCheck = pais.getFormularioCollection();
            for (Formulario formularioCollectionOrphanCheckFormulario : formularioCollectionOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Pais (" + pais + ") cannot be destroyed since the Formulario " + formularioCollectionOrphanCheckFormulario + " in its formularioCollection field has a non-nullable pais field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            em.remove(pais);
            //em.getTransaction().commit();
        } catch(Exception e) {
            throw e;
        }
    }

    /*public List<Pais> findPaisEntities() {
        return findPaisEntities(true, -1, -1);
    }*/

    public List<Pais> findPaisEntities(EntityManager em) throws Exception {
        return findPaisEntities(true, -1, -1, em);
    }

    /*public List<Pais> findPaisEntities(int maxResults, int firstResult) {
        return findPaisEntities(false, maxResults, firstResult);
    }*/

    public List<Pais> findPaisEntities(int maxResults, int firstResult, EntityManager em) throws Exception {
        return findPaisEntities(false, maxResults, firstResult, em);
    }

    /*private List<Pais> findPaisEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from Pais as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }*/

    private List<Pais> findPaisEntities(boolean all, int maxResults, int firstResult, EntityManager em) throws Exception {
        //EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select object(o) from Pais as o");
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } catch(Exception e) {
            throw e;
        }
    }

    /*public Pais findPais(String id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Pais.class, id);
        } finally {
            em.close();
        }
    }*/

    public Pais findPais(String id, EntityManager em) throws Exception {
        //EntityManager em = getEntityManager();
        try {
            return em.find(Pais.class, id);
        } catch(Exception e) {
            throw e;
        }
    }

    public Pais findPaisByName(String name, EntityManager em){
        Query queryPaisPorNombre = em.createNamedQuery("Pais.findByCountry");
        queryPaisPorNombre.setParameter("country", name);
        //Collection employees = queryEmployessByFirstName.getResultList();
        if(((List<Pais>) queryPaisPorNombre.getResultList()).size()==0){
            throw new ArrayIndexOutOfBoundsException();
        }
        return ((List<Pais>) queryPaisPorNombre.getResultList()).get(0);        
    }



    /*public int getPaisCount() {
        EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select count(o) from Pais as o");
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }*/

    public int getPaisCount(EntityManager em) throws Exception {
        //EntityManager em = getEntityManager();
        try {
            Query q = em.createQuery("select count(o) from Pais as o");
            return ((Long) q.getSingleResult()).intValue();
        } catch(Exception e) {
            throw e;
        }
    }

}
